// src/composables/crud/useCRUD.ts
import { ElMessageBox } from "element-plus";
import { message } from "@/utils/message";

type IdType = string | number;

type CrudAction = "create" | "update" | "delete" | "read" | "batch";

type MessageBoxAction = "confirm" | "cancel" | "close";

interface CrudMessages {
  createSuccess?: string;
  updateSuccess?: string;
  deleteSuccess?: string;
  createError?: string;
  updateError?: string;
  deleteError?: string;
  readError?: string;
  batchSuccess?: string;
  batchError?: string;
}

interface CRUDOptions {
  messages?: CrudMessages;
  showSuccessMessages?: boolean;
  showErrorMessages?: boolean;
  validateId?: (id: IdType) => void;
}

interface CrudService<TPayload, TResult, TReadResult = TResult> {
  create?: (payload: TPayload) => Promise<TResult>;
  update?: (id: IdType, payload: TPayload) => Promise<TResult>;
  delete?: (id: IdType) => Promise<TResult>;
  read?: (id: IdType) => Promise<TReadResult>;
}

const CANCEL_ACTIONS: MessageBoxAction[] = ["cancel", "close"];

const isCancelAction = (action: unknown): action is MessageBoxAction => {
  return (
    typeof action === "string" &&
    CANCEL_ACTIONS.includes(action as MessageBoxAction)
  );
};

function ensureMethod<
  TPayload,
  TResult,
  TReadResult,
  K extends keyof CrudService<TPayload, TResult, TReadResult>
>(service: CrudService<TPayload, TResult, TReadResult>, method: K) {
  const fn = service[method];
  if (!fn) {
    throw new Error(`apiService 未实现 ${String(method)} 方法`);
  }
  return fn as NonNullable<CrudService<TPayload, TResult, TReadResult>[K]>;
}

export function useCRUD<TPayload, TResult = unknown, TReadResult = TResult>(
  apiService: CrudService<TPayload, TResult, TReadResult>,
  options: CRUDOptions = {}
) {
  const {
    messages = {},
    showSuccessMessages = false,
    showErrorMessages = true,
    validateId = id => {
      if (id === undefined || id === null || id === "") {
        throw new Error("无效的ID");
      }
    }
  } = options;

  const defaultMessages: Required<CrudMessages> = {
    createSuccess: "创建成功",
    updateSuccess: "更新成功",
    deleteSuccess: "删除成功",
    createError: "创建失败",
    updateError: "更新失败",
    deleteError: "删除失败",
    readError: "获取详情失败",
    batchSuccess: "操作成功",
    batchError: "操作失败",
    ...messages
  };

  const notifySuccess = (text: string) => {
    if (showSuccessMessages) {
      message(text, { type: "success" });
    }
  };

  const notifyError = (action: CrudAction, error: any) => {
    if (!showErrorMessages) return;
    const fallbackMap: Record<CrudAction, string> = {
      create: defaultMessages.createError,
      update: defaultMessages.updateError,
      delete: defaultMessages.deleteError,
      read: defaultMessages.readError,
      batch: defaultMessages.batchError
    };
    const fallback = fallbackMap[action];
    message(error?.message || fallback, { type: "error" });
  };

  // 创建
  const create = async (data: TPayload) => {
    const createFn = ensureMethod(apiService, "create");
    try {
      const response = await createFn(data);
      notifySuccess(defaultMessages.createSuccess);
      return response;
    } catch (error: any) {
      notifyError("create", error);
      console.error(defaultMessages.createError, error);
      throw error;
    }
  };

  // 更新（支持不同类型的 ID）
  const update = async (id: IdType, data: TPayload) => {
    const updateFn = ensureMethod(apiService, "update");
    try {
      const response = await updateFn(id, data);
      notifySuccess(defaultMessages.updateSuccess);
      return response;
    } catch (error: any) {
      notifyError("update", error);
      console.error(defaultMessages.updateError, error);
      throw error;
    }
  };

  // 删除（支持不同类型的 ID）
  const remove = async (id: IdType) => {
    const deleteFn = ensureMethod(apiService, "delete");
    try {
      await ElMessageBox.confirm("确定要删除这条数据吗？", "确认删除", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      });
    } catch (error: any) {
      if (isCancelAction(error)) {
        throw error;
      }
      notifyError("delete", error);
      console.error(defaultMessages.deleteError, error);
      throw error;
    }

    try {
      const response = await deleteFn(id);
      notifySuccess(defaultMessages.deleteSuccess);
      return response;
    } catch (error: any) {
      if (isCancelAction(error)) {
        throw error;
      }
      notifyError("delete", error);
      console.error(defaultMessages.deleteError, error);
      throw error;
    }
  };

  // 获取详情（支持不同类型的 ID）
  const read = async (id: IdType) => {
    const readFn = ensureMethod(apiService, "read");
    try {
      validateId(id);

      const response = await readFn(id);
      return response;
    } catch (error: any) {
      notifyError("read", error);
      console.error(defaultMessages.readError, error);
      throw error;
    }
  };

  // 批量操作
  const batchOperation = async (
    operation: (params: any) => Promise<any>,
    params: any,
    successMessage: string = defaultMessages.batchSuccess,
    errorMessage: string = defaultMessages.batchError
  ) => {
    try {
      const response = await operation(params);
      notifySuccess(successMessage);
      return response;
    } catch (error: any) {
      if (showErrorMessages) {
        message(error.message || errorMessage, { type: "error" });
      }
      console.error(errorMessage, error);
      throw error;
    }
  };

  return {
    create,
    update,
    remove,
    read,
    batchOperation
  };
}
